# -*- mode: python; coding: utf-8; -*-
##--------------------------------------------------------------------------##
##
## Copyright (C) 1998-2003 Markus Oberhumer <markus@oberhumer.com>
## Copyright (C) 2003 Mt. Hood Playing Card Co.
## Copyright (C) 2005-2010 Skomoroh <skomoroh@users.sourceforge.net>
## Copyright (C) 2010-2013 Jeremy Austin-Bardo <tjaustinbardo@gmail.com>
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program.  If not, see <http://www.gnu.org/licenses/>.
##
##--------------------------------------------------------------------------##
"""
"""
from .. import formlib as layout

LEFT, RIGHT = layout.LEFT, layout.RIGHT


class KlondikeLayout(layout.Layout):
    """
    static block:
      - foundations [N]. (horz SUIT * 2. max 10 cols)
      - rows [S foundation]. `_offset` if `playcards`. `ncols` wide.
      - reserves [S]. (horz) `_offset` if `holdcards`. `ncards` if
        `reserve_texts`.

    dynamic block: align [LEFT | RIGHT].
      - talon [NW | NE].
      - waste [E talon | W talon]. `wastecards` ignored.

    :CVariables:
        _offset: func
          .. dict('ycards': [play|hold]cards)
          Margin and offset is below piles.

        _halign: func
          .. (max(ncols, f_cols + int(_has_waste)) - cols) * HXS
          center static piles horz.
    """
    _offset = lambda self, cards: {'ycards': cards}
    _halign = lambda self, max_rows, piles: (max_rows - piles) * self.HXS

    def create(self, rows, ncols=None, playcards=16, bases=None,
               reserves=0, holdcards=0, reserve_texts=False,
               texts=True, align=LEFT, **kw):
        """
        create(rows[, ncols=rows, playcards=16, bases=suits * decks,
               reserves=0, holdcards=0, reserve_texts=False,
               texts=True, align=LEFT]) -> None

        :Parameters:
          rows : int
            Num of `s.rows` to include.

          ncols : int
            Num of horz piles before starting new row. Default `ROWS`.

          playcards : int
            Num of possible cards as margin on each pile on `s.rows`. A value
            of 0 sets no offset and a value greater sets an offset. Default
            `16`.

          bases : tuple | list
            Value of each `suit` capabilty on `s.foundations`. Len is num of
            piles to include. Default `SUITS * DECKS`.

          reserves : int
            Num of `s.reserves` piles to include. Default `0`.

          holdcards : int
            Num of possible cards as margin on each pile on `s.reserves`. A
            value of 0 sets no offset and a value greater sets an offset.
            Default `0`.

          reserve_texts : bool
            Whether to include num cards text label for `s.reserves`. Default
            `False`.

          texts : bool
            Whether to include num cards text label for `s.talon` and possible
            `s.waste`. Default `True`.

          align : LEFT | RIGHT
            Dynamic placement of `s.talon`, possible `s.waste`, and possible
            `s.reserves`. `s.foundations` placement is opposite side. Default
            `LEFT`
        """
        l, s = self, self.s
        ncols = ncols or rows
        t_cols = 2 + int(l._has_waste)
        # Set foundation
        bases = bases if type(bases) in (list, tuple) else l.SUITS
        f_cols = min(10, (len(bases) / l.NDECKS) * min(2, l.NDECKS))
        # Set remain alignment
        max_cols = max(t_cols + f_cols, reserves, ncols)
        row_align = lambda piles: l._halign(max_cols, piles)
        # Allow sub class
        ix = max(l.size.width, l.XM)
        # Static align foundation N
        dx = (ix if align == RIGHT else ix + t_cols * l.HXS)
        l._set_horz_foundations(x=dx + row_align(t_cols + f_cols), y=l.YM,
                                ncols=f_cols, bases=bases)
        # Static align row S foundation
        sy = l.TEXT_HEIGHT if texts else 0
        sy += l.TEXT_HEIGHT if l._has_waste else 0
        l._set_rows(x=ix + row_align(rows), y=l.size.height + sy, rows=rows,
                    ncols=ncols, **l._offset(playcards))
        # Static align reserve S
        dy = l.TEXT_HEIGHT if reserve_texts else 0
        l._set_horz_reserves(x=ix + row_align(reserves), y=l.size.height + dy,
                            reserves=reserves, reserve_texts=reserve_texts,
                            anchor='n', **l._offset(holdcards))
        # Dynamic align to `align` edge talon and waste
        dx = ix if align == LEFT else l.size.width - l.XS
        dy = (len(bases) / f_cols + int(len(bases) % f_cols > 0) - 1) * l.HYS
        l._set_horz_talon(x=dx, y=l.YM + dy, texts=texts, align=align,
                          anchor='s', wastecards=0)
        anchor = 'w' if align== RIGHT else'e'
        s['talon'].set_rounds(anchor='ss' if l._has_waste else anchor)


class CrescentLayout(KlondikeLayout):
    """
    static block:
      - foundations [N]. (horz SUIT * 2. max 10 cols)
      - rows [S foundation]. `_offset` if `playcards`. `ncols` wide.
      - reserves [S]. (horz) `_offset` if `holdcards`. `ncards` if
        `reserve_texts`.

    dynamic block: align [LEFT | RIGHT].
      - talon [NW | NE].
      - waste [E talon | W talon]. `wastecards` ignored.

    :CVariables:
        _offset: func
          .. dict('xcards': [play|hold]cards)
          Margin and offset is right piles.

        _halign: func
          .. 0
          no static piles horz.
    """
    _offset = lambda self, cards: {'xcards': cards}
    _halign = lambda self, max_rows, piles: 0